package com.click.app.webapp.action;

import com.click.app.model.LaundryItem;
import com.click.app.model.LaundryRequest;
import com.click.app.model.LaundryRequestItem;
import com.click.app.model.LaundryType;
import com.click.app.model.ModelSize;
import com.click.app.model.PantDesign;
import com.click.app.model.SeamStorage;
import com.click.app.model.SizeRank;
import com.click.app.model.TradeMark;
import com.click.app.service.GenericManager;
import com.click.app.service.LaundryItemManager;
import com.click.app.service.LaundryRequestItemManager;
import com.click.app.service.PantDesignManager;
import com.click.app.service.SeamStorageManager;
import com.click.app.webapp.reportObjects.LaundryRequestTable;
import com.click.app.webapp.reportObjects.PantDesignWithoutModelSize;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

/**
 * @author Joel Chuca
 */
public class LaundryRequestItemAction extends BaseAction {

    private PantDesignManager pantDesignManager;
    private SeamStorageManager seamStorageManager;
    private LaundryRequestItemManager laundryRequestItemManager;
    private GenericManager<LaundryRequest, Long> laundryRequestManager;
    private GenericManager<TradeMark, Long> tradeMarkManager;
    private GenericManager<LaundryType, Long> laundryTypeManager;
    private GenericManager<SizeRank, Long> sizeRankManager;
    private LaundryItemManager laundryItemManager;
    private LaundryRequest laundryRequest;
    private LaundryRequestItem laundryRequestItem;
    //private SeamStorage seamStorage;
    private PantDesign pantDesign;
    private List laundryRequestItems;
    //private List seamStorages;
    private List<SeamStorage> seamStoragesAvailable;
    private List laundryTypes;
    private List<PantDesign> pantDesigns;
    private Set<PantDesignWithoutModelSize> pantDesignWithoutMSs;
    private PantDesignWithoutModelSize pdwms;
    //private List pantDesignEnables;
    private Set<ModelSize> modelSizes;
    //private Set<ModelSize> modelSizeInputs;
    private List<LaundryItem> laundryItems;
    private String[] quantities;
    private String[] quantitiesUser;
    private List<Integer> quantitiesIndex;
    private Long id;
    private Long idLaundryRequest;
    private LaundryRequestTable laundryRequestTable;
    private List<TradeMark> listTradeMark;
    private TradeMark tradeMark;

    public void setLaundryRequestItemManager(LaundryRequestItemManager laundryRequestItemManager) {
        this.laundryRequestItemManager = laundryRequestItemManager;
    }

    public void setLaundryRequestManager(GenericManager<LaundryRequest, Long> laundryRequestManager) {
        this.laundryRequestManager = laundryRequestManager;
    }

    public void setLaundryTypeManager(GenericManager<LaundryType, Long> laundryTypeManager) {
        this.laundryTypeManager = laundryTypeManager;
    }

    public void setPantDesignManager(PantDesignManager pantDesignManager) {
        this.pantDesignManager = pantDesignManager;
    }

    public void setSeamStorageManager(SeamStorageManager seamStorageManager) {
        this.seamStorageManager = seamStorageManager;
    }

    public void setTrademarkManager(GenericManager<TradeMark, Long> trademarkManager) {
        this.tradeMarkManager = trademarkManager;
    }

    public void setSizeRankManager(GenericManager<SizeRank, Long> sizeRankManager) {
        this.sizeRankManager = sizeRankManager;
    }

    public void setLaundryItemManager(LaundryItemManager laundryItemManager) {
        this.laundryItemManager = laundryItemManager;
    }

    public String[] getQuantitiesUser() {
        return quantitiesUser;
    }

    public void setQuantitiesUser(String[] quantitiesUser) {
        this.quantitiesUser = quantitiesUser;
    }
    

    public List getLaundryRequestItems() {
        return laundryRequestItems;
    }

    public List getLaundryTypes() {
        return laundryTypes;
    }

    public List<LaundryItem> getLaundryItems() {
        return laundryItems;
    }

    public String[] getQuantities() {
        return quantities;
    }

    public void setQuantities(String[] quantities) {
        this.quantities = quantities;
    }

    public List<TradeMark> getListTradeMark() {
        return listTradeMark;
    }

    public void setListTradeMark(List<TradeMark> listTradeMark) {
        this.listTradeMark = listTradeMark;
    }

    public List getPantDesigns() {
        return pantDesigns;
    }

    public List<SeamStorage> getSeamStoragesAvailable() {
        return seamStoragesAvailable;
    }

    public Set<ModelSize> getModelSizes() {
        return modelSizes;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Long getIdLaundryRequest() {
        return idLaundryRequest;
    }

    public void setIdLaundryRequest(Long idLaundryRequest) {
        this.idLaundryRequest = idLaundryRequest;
    }

    public LaundryRequest getLaundryRequest() {
        return laundryRequest;
    }

    public void setLaundryRequest(LaundryRequest laundryRequest) {
        this.laundryRequest = laundryRequest;
    }

    public LaundryRequestItem getLaundryRequestItem() {
        return laundryRequestItem;
    }

    public void setLaundryRequestItem(LaundryRequestItem laundryRequestItem) {
        this.laundryRequestItem = laundryRequestItem;
    }

    public LaundryRequestTable getLaundryRequestTable() {
        return laundryRequestTable;
    }

    public PantDesign getPantDesign() {
        return pantDesign;
    }

    public void setPantDesign(PantDesign pantDesign) {
        this.pantDesign = pantDesign;
    }

    public String list() {

        if (idLaundryRequest != null) {
            laundryRequest = laundryRequestManager.get(idLaundryRequest);
            getSession().setAttribute("laundryRequest", laundryRequest);
        } else {
            laundryRequest = ((LaundryRequest) getSession().getAttribute("laundryRequest"));
        }

        if (laundryRequest != null) {
            laundryRequest = laundryRequestManager.get(laundryRequest.getId());
            modelSizes = sizeRankManager.get(new Long(1)).getModelSizes(); // Constant for sizes .... 
            getSession().setAttribute("modelSizes", modelSizes);

            laundryRequestTable = new LaundryRequestTable(laundryRequest.getLaundryRequestItems(), laundryItemManager, modelSizes);

        } else {
            System.out.println("laundryRequest is null");
            return ERROR;
        }
        return SUCCESS;
    }

    public String edit() {
        System.out.println("LaundryRequestItemAction -> edit()");

        laundryRequest = ((LaundryRequest) getSession().getAttribute("laundryRequest"));
        listTradeMark = seamStorageManager.findEnablesTradeMark();
        pantDesignWithoutMSs = new HashSet<PantDesignWithoutModelSize>();

        if (getSession().getAttribute("tradeMarkId") != null) {
            tradeMark = tradeMarkManager.get((Long) getSession().getAttribute("tradeMarkId"));
            pantDesigns = seamStorageManager.findByTradeMark(tradeMark.getId());
            for (Iterator<PantDesign> it = pantDesigns.iterator(); it.hasNext();) {
                PantDesign pd = it.next();
                PantDesignWithoutModelSize pdwmsAux = new PantDesignWithoutModelSize();

                pdwmsAux.setId(pd.getMaterial().getId() + "-" + pd.getModel().getId());
                pdwmsAux.setMaterial(pd.getMaterial());
                pdwmsAux.setModel(pd.getModel());

                pantDesignWithoutMSs.add(pdwmsAux);
            }
        }

        if (getSession().getAttribute("pdwms") != null) {
            pdwms = (PantDesignWithoutModelSize) getSession().getAttribute("pdwms");
        }

        modelSizes = ((Set<ModelSize>) getSession().getAttribute("modelSizes"));
        laundryTypes = laundryTypeManager.getAll();

        if (id != null) {
            laundryRequestItem = laundryRequestItemManager.get(id);
            pantDesign = laundryRequestItem.getLaundryItems().get(0).getPantDesign();

            // Verificacion si existe prendas creadas en almacen de costura
            if (existNull(seamStoragesAvailable)) {
                errorMessage("No existe prendas creadas en el almacen de costura");
                return "error";
            }

            laundryItems = laundryItemManager.findByOrderSize(laundryRequestItem.getId());
            quantities = new String[modelSizes.size()];
            for (int i = 0; i < modelSizes.size(); i++) {
                quantities[i] = laundryItems.get(i).getQuantity() + "";
            }
            getSession().setAttribute("pantDesign", pantDesign);
            getSession().setAttribute("seamStoragesAvailable", seamStoragesAvailable);

        } else {
            laundryRequestItem = ((LaundryRequestItem) getSession().getAttribute("laundryRequestItem"));

            // verify if was sended to reload
            if (laundryRequestItem != null) {
                // pantDesign = (PantDesign) getSession().getAttribute("pantDesign");
                seamStoragesAvailable = ((List<SeamStorage>) getSession().getAttribute("seamStoragesAvailable"));
                if (seamStoragesAvailable != null) {
                    // Verificacion si existe prendas creadas en almacen de costura
                    if (existNull(seamStoragesAvailable)) {
                        errorMessage("No existe prendas creadas en el almacen de costura");
                        return "error";
                    }
                    quantitiesIndex = new ArrayList<Integer>();
                    quantities = new String[modelSizes.size()];
                    int i = 0;
                    for (Iterator it = modelSizes.iterator(); it.hasNext(); i++) {
                        ModelSize mSizes = (ModelSize) it.next();
                        int index = 0;

                        for (SeamStorage seamStorage : seamStoragesAvailable) {
                            if (seamStorage.getPantDesign().getModelSize().equals(mSizes)) {
                                break;
                            }
                            index++;
                        }
                        if (seamStoragesAvailable.size() == index) {
                            quantities[i] = 0 + "";
                        } else {
                            quantities[i] = seamStoragesAvailable.get(index).getStock() + "";
                            quantitiesIndex.add(i);
                        }
                        quantitiesUser = quantities;
                    }
                    getSession().setAttribute("quantities", quantities);
                    getSession().setAttribute("quantitiesIndex", quantitiesIndex);
                }

            } else {
                laundryRequestItem = new LaundryRequestItem();
                laundryRequestItem.setQuantity(0);
                laundryRequestItem.setFailQuantity(0);
                laundryRequestItem.setUnitTotalPrice(0D);
                laundryRequestItem.setFailUnitPrice(0D);
                getSession().setAttribute("laundryRequestItem", laundryRequestItem);
            }
        }
        System.out.println("LaundryRequestItemAction -> end edit()");

        return SUCCESS;
    }

    public String save() {
        System.out.println("LaundryRequestItemAction -> save() ... reload");
        // verify correct dates of laundryRequestItem entity
        if (tradeMark.getId() != null && !tradeMark.getId().equals(new Long(-1))) {
            getSession().setAttribute("tradeMarkId", tradeMark.getId());
        }
        if (pdwms != null && !pdwms.getId().equals("-1") && (tradeMark.getId() != null && !tradeMark.getId().equals(new Long(-1)))) {
            String codes[] = pdwms.getId().split("-");
            laundryRequest = ((LaundryRequest) getSession().getAttribute("laundryRequest"));
            modelSizes = ((Set<ModelSize>) getSession().getAttribute("modelSizes"));

            seamStoragesAvailable = seamStorageManager.findByMaterialAndModelAndTradeMarkAndSizes(
                    new Long(codes[0]), new Long(codes[1]), (Long) getSession().getAttribute("tradeMarkId"), modelSizes);

            getSession().setAttribute("seamStoragesAvailable", seamStoragesAvailable);
            getSession().setAttribute("pdwms", pdwms);
        }

        System.out.println("LaundryRequestItemAction -> end save()");

        return "reload";
    }

    public String saveButton() {

        System.out.println("LaundryRequestItemAction -> saveButton()");

        if (cancel != null) {
            return CANCEL;
        }

        if (delete != null) {
            //return delete();
        }

        boolean isNew = false;
        isNew = (laundryRequestItem.getId() == null);

        String result = verifyInputDatas();
        if (result != null) {
            return result;
        }

        tradeMark = tradeMarkManager.get((Long) getSession().getAttribute("tradeMarkId"));
        laundryRequest = (LaundryRequest) getSession().getAttribute("laundryRequest");
        modelSizes = ((Set<ModelSize>) getSession().getAttribute("modelSizes"));
        quantities =((String[]) getSession().getAttribute("quantities"));
        quantitiesIndex =((List<Integer>) getSession().getAttribute("quantitiesIndex"));
        Integer totalQuantity = 0;
        seamStoragesAvailable = ((List<SeamStorage>) getSession().getAttribute("seamStoragesAvailable"));

        for (int i = 0; i < quantitiesUser.length; i++) {
            String string = quantitiesUser[i];
            Integer index = quantitiesIndex.get(i);
            quantities[index]=string;
        }

        int iAux = 0;
        for (Iterator it = modelSizes.iterator(); it.hasNext(); iAux++) {
            ModelSize msAux = (ModelSize) it.next();
            int index = 0;
            for (SeamStorage seamSt : seamStoragesAvailable) {
                if (seamSt.getPantDesign().getModelSize().equals(msAux)) {
                    break;
                }
                index++;
            }
            if (index < seamStoragesAvailable.size()) {
                Integer quantity = Integer.parseInt(quantities[iAux]);
                if (quantity > seamStoragesAvailable.get(index).getStock()) {
                    saveMessage("Quantity exceded the stock available");
                    return "reload";
                } else if (quantity < 0) {
                    saveMessage("Quantity incorrect: the quantity is less than zero");
                    return "reload";
                }
                totalQuantity += quantity;
            }
        }

        laundryRequestItem.setQuantity(totalQuantity);
        laundryRequestItem.setTotalPrice(0D);
        laundryRequestItem.setFailQuantity(0);
        laundryRequestItem.setFailUnitPrice(0D);
        laundryRequestItem.setFailTotalPrice(0D);
        laundryRequestItem.setTradeMark(tradeMark);
        laundryRequestItem.setLaundryRequest(laundryRequest);
        laundryRequestItem = laundryRequestItemManager.save(laundryRequestItem);

        laundryItems = new ArrayList<LaundryItem>();

        iAux = 0;
        for (Iterator it = modelSizes.iterator(); it.hasNext(); iAux++) {
            ModelSize msAux = (ModelSize) it.next();
            int index = 0;
            for (SeamStorage seamSt : seamStoragesAvailable) {
                if (seamSt.getPantDesign().getModelSize().equals(msAux)) {
                    break;
                }
                index++;
            }
            if (index < seamStoragesAvailable.size()) {
                SeamStorage seamStorage = seamStoragesAvailable.get(index);
                Integer quantity = Integer.parseInt(quantities[iAux]);
                if (quantity > 0) {
                    LaundryItem laundryItem = new LaundryItem();
                    laundryItem.setPantDesign(seamStorage.getPantDesign());
                    laundryItem.setQuantity(quantity);
                    laundryItem.setFailQuantity(0);

                    laundryItem.setFailTotalPrice(0D);
                    laundryItem.setFailUnitPrice(0D);
                    laundryItem.setTotalPrice(0D);
                    laundryItem.setUnitPrice(0D);

                    laundryItem.setLaundryRequestItem(laundryRequestItem);
                    laundryItem = laundryItemManager.save(laundryItem);
                    seamStorage.decrementStock(quantity);
                    seamStorage = seamStorageManager.save(seamStorage);
                }
            }

        }
        
        laundryRequest = laundryRequestManager.get(laundryRequest.getId());
        laundryRequest.setTotalPrice(laundryRequest.getTotalPrice() + laundryRequestItem.getTotalPrice());
        laundryRequest.setQuantity(laundryRequest.getQuantity() + laundryRequestItem.getQuantity());
        laundryRequest = laundryRequestManager.save(laundryRequest);

        getSession().setAttribute("laundryRequest", laundryRequest);
        getSession().setAttribute("pantDesign", null);
        getSession().setAttribute("laundryRequestItem", null);
        getSession().setAttribute("seamStoragesAvailable", null);

        if (isNew) {
            saveMessage(getText("laundryRequestItem.added"));
            return SUCCESS;
        } else {
            saveMessage(getText("laundryRequestItem.updated"));
            return INPUT;
        }
    }

    public String delete() {

        laundryRequest = (LaundryRequest) getSession().getAttribute("laundryRequest");
        laundryRequestItem = laundryRequestItemManager.get(laundryRequestItem.getId());
        //pantDesign = laundryItems.get(0).getPantDesign();

//        for (LaundryItem laundryItem : laundryRequestItem.getLaundryItems()) {
//            SeamStorage seamStorage = seamStorageManager.findByPantDesignAndTradeMark(laundryItem.getPantDesign().getId(), laundryRequest.getTradeMark().getId()).get(0);
//            seamStorage.incrementStock(laundryItem.getQuantity());
//            seamStorage = seamStorageManager.save(seamStorage);
//        }

        laundryRequest = laundryRequestManager.get(laundryRequest.getId());
        laundryRequest.setQuantity(laundryRequest.getQuantity() - laundryRequestItem.getQuantity());
        laundryRequest.setTotalPrice(laundryRequest.getTotalPrice() - laundryRequestItem.getTotalPrice());
        laundryRequest = laundryRequestManager.save(laundryRequest);

        // this sentence delete laundryRequestItem whith its laundryItems
        laundryRequestItemManager.remove(laundryRequestItem.getId());

        getSession().setAttribute("pantDesign", null);
        getSession().setAttribute("laundryRequestItem", null);

        saveMessage(getText("laundryRequestItem.deleted"));

        return "delete";
    }

    public String verifyInputDatas() {
        String result = null;

        try {
            for (int i = 0; i < quantitiesUser.length; i++) {
                Integer quantity = Integer.parseInt(quantitiesUser[i]);
            }

        } catch (Exception e) {
            System.out.println("LaundryRequestItemAction exception: " + e.getMessage());
            saveMessage("Quantity incorrect: the number does't have the format correct");
            result = "reload";
        }

        if (!(laundryRequestItem.getLaundryType() != null && laundryRequestItem.getLaundryType().getId() > 0)) {
            saveMessage("Laundry Type wasn't selected");
            result = "reload";
        }

//        if (laundryRequestItem.getUnitPrice() == null) {
//            saveMessage(getText("laundryRequestItemRequired.unitPrice"));
//            result = "reload";
//        } else {
//            if (laundryRequestItem.getUnitPrice() < 0.001) {
//                saveMessage(getText("laundryRequestItemRequired.unitPrice"));
//                result = "reload";
//            }
//        }

        return result;
    }

    public String help() {
        return SUCCESS;
    }

    public String finalizeLaundryRequestItem() {
        getSession().setAttribute("laundryRequest", null);
        getSession().setAttribute("laundryRequestItem", null);
        getSession().setAttribute("pantDesign", null);
        return SUCCESS;
    }

    public boolean existNull(List<SeamStorage> list) {
        for (SeamStorage seamStorage : list) {
            if (seamStorage.getId() == null) {
                return true;
            }
        }
        return false;
    }

    public Set<PantDesignWithoutModelSize> getPantDesignWithoutMSs() {
        return pantDesignWithoutMSs;
    }

    public void setPantDesignWithoutMSs(Set<PantDesignWithoutModelSize> pantDesignWithoutMSs) {
        this.pantDesignWithoutMSs = pantDesignWithoutMSs;
    }

    public PantDesignWithoutModelSize getPdwms() {
        return pdwms;
    }

    public void setPdwms(PantDesignWithoutModelSize pdwms) {
        this.pdwms = pdwms;
    }

    public TradeMark getTradeMark() {
        return tradeMark;
    }

    public void setTradeMark(TradeMark tradeMark) {
        this.tradeMark = tradeMark;
    }

    public GenericManager<TradeMark, Long> getTradeMarkManager() {
        return tradeMarkManager;
    }

    public void setTradeMarkManager(GenericManager<TradeMark, Long> tradeMarkManager) {
        this.tradeMarkManager = tradeMarkManager;
    }
}
